﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using CNav.Business.Validation;
using CNav.Common;
using CNav.DataEntity;
using CNav.Domain;
using CNav.Domain.Admin;

namespace CNav.Business.Services
{
    public interface IAdminConfigurationService
    {
        ResponseData<List<FormConfiguration>> GetFormConfigurationList();
        ResponseData<FormConfiguration> GetFormConfigurationById(int id);
        ResponseData<bool> AddFormConfiguration(FormConfiguration formConfiguration);
        ResponseData<FormConfiguration> UpdateFormConfiguration(FormConfiguration formConfiguration);
        ResponseData<bool> UpdateFormConfiguration(IList<FormConfiguration> formConfigurations);
        ResponseData<bool> DeleteFormConfiguration(int id);
    }

    public class AdminConfigurationService : ServiceBase, IAdminConfigurationService
    {
        public ResponseData<List<FormConfiguration>> GetFormConfigurationList()
        {
            var response = new ResponseData<List<FormConfiguration>>();
            var result = Context.Get<FormConfigurationDto>().Include(f => f.Form).ToList();

            var formConfigs = result.Select(fc => new FormConfiguration
            {
                ID = fc.ID,
                Stage = fc.Stage,
                FormID = fc.FormID ?? 0,
                FormName = fc.Form != null ? fc.Form.Name : string.Empty
            }).ToList();

            response.Data = formConfigs;

            return response;
        }

        public ResponseData<FormConfiguration> GetFormConfigurationById(int id)
        {
            var response = new ResponseData<FormConfiguration>();
            var result = Context.Get<FormConfigurationDto>(f => f.ID == id).Include(f => f.Form).ToList().FirstOrDefault();

            if (result != null)
            {
                response.Data = new FormConfiguration
                {
                    ID = result.ID,
                    Stage = result.Stage,
                    FormID = result.FormID ?? 0,
                    FormName = result.Form != null ? result.Form.Name : string.Empty
                };
                return response;
            }

            response.Error = new[] { "Invalid Form Configuration id" };
            return response;
        }

        public ResponseData<bool> AddFormConfiguration(FormConfiguration formConfiguration)
        {
            var response = new ResponseData<bool>();

            var validator = new FormConfigurationValidation();
            var result = validator.Validate(formConfiguration);
            if (result.IsValid)
            {
                var formConfigDto = new FormConfigurationDto();

                formConfigDto.Stage = formConfiguration.Stage;
                formConfigDto.FormID = formConfiguration.FormID;

                Context.Repository<FormConfigurationDto>().Add(formConfigDto);
                Context.Commit();

                response.Data = true;
                return response;
            }

            response.Error = result.ErrorList();
            return response;
        }

        public ResponseData<FormConfiguration> UpdateFormConfiguration(FormConfiguration formConfiguration)
        {
            var response = new ResponseData<FormConfiguration>();
            var validator = new FormConfigurationValidation();

            var result = validator.Validate(formConfiguration);
            if (result.IsValid)
            {
                FormConfigurationDto configurationDto = Context.Get<FormConfigurationDto>(fc => fc.ID == formConfiguration.ID).ToList().FirstOrDefault();

                if (configurationDto != null)
                {
                    configurationDto.Stage = formConfiguration.Stage;
                    configurationDto.FormID = formConfiguration.FormID;

                    Context.Repository<FormConfigurationDto>().Update(configurationDto);
                    Context.Commit();
                    response = GetFormConfigurationById(formConfiguration.ID);

                    return response;
                } 
                
                response.Error = new[] { "Form Configuration provided does not exist." };
                return response;
            }

            response.Error = result.ErrorList();
            return response;

        }

        public ResponseData<bool> UpdateFormConfiguration(IList<FormConfiguration> formConfigurations)
        {
            var response = new ResponseData<bool>();
            bool isValid = true;
            var errList = new List<string>();

            var validator = new FormConfigurationValidation();
            foreach (var formConfiguration in formConfigurations)
            {
                var result = validator.Validate(formConfiguration);
                if (result.IsValid)
                    continue;

                errList.AddRange(result.ErrorList());
                isValid = false;
            }

            if (isValid)
            {
                using (var scope = new TransactionScope())
                {
                    foreach (var formConfiguration in formConfigurations)
                    {
                        var config = formConfiguration;
                        FormConfigurationDto configurationDto = Context.Get<FormConfigurationDto>(fc => fc.ID == config.ID).ToList().FirstOrDefault();

                        if (configurationDto != null)
                        {
                            configurationDto.FormID = config.FormID;
                            Context.Repository<FormConfigurationDto>().Update(configurationDto);
                        }
                    }

                    Context.Commit();
                    scope.Complete();

                    response.Data = true;
                    return response;
                }
            }
            response.Error = new[] { "Form Configuration provided does not exist." };
            return response;
        }

        public ResponseData<bool> DeleteFormConfiguration(int id)
        {
            var response = new ResponseData<bool>();

            FormConfigurationDto configurationDto = Context.Get<FormConfigurationDto>(fc => fc.ID == id).ToList().FirstOrDefault();
            if (configurationDto != null)
            {
                Context.Repository<FormConfigurationDto>().Delete(configurationDto);
                Context.Commit();

                response.Data = true;
                return response;
            }
            response.Error = new[] { "Form Configuration provided does not exist." };
            return response;
        }
    }
}
